package com.danco.training.zaneuskaya.controller;

import java.io.IOException;
import java.util.List;

import com.danco.training.zaneuskaya.api.BookController;
import com.danco.training.zaneuskaya.api.ClaimController;
import com.danco.training.zaneuskaya.communication.MessageAnalyzer;
import com.danco.training.zaneuskaya.dependency.DependencyConfiguration;
import com.danco.training.zaneuskaya.domain.Book;
import com.danco.training.zaneuskaya.domain.Claim;
import com.danco.training.zaneuskaya.view.IOUtil;

public class ClaimControllerImpl implements ClaimController {

	private static final String UPDATE_ENTITY = "com.danco.training.zaneuskaya.service.impl.ClaimServiceImpl;updateEntity";

	private static final String READ_ENTITY_LIST_FROM_FILE = "com.danco.training.zaneuskaya.service.impl.ClaimServiceImpl;readEntityList";

	private static final String SAVE_ENTITY_LIST_TO_FILE = "com.danco.training.zaneuskaya.service.impl.ClaimServiceImpl;saveEntityListToFile";

	private static final String REMOVE_ENTITY_BY_ID = "com.danco.training.zaneuskaya.service.impl.ClaimServiceImpl;removeEntityById";

	private static final String ADD_ENTITY = "com.danco.training.zaneuskaya.service.impl.ClaimServiceImpl;addEntity";

	private static final String BOOK_SERVICE_GET_BY_ID = "com.danco.training.zaneuskaya.service.impl.BookServiceImpl;getById";

	private static final String GET_BY_ID = "com.danco.training.zaneuskaya.service.impl.ClaimServiceImpl;getById";

	private static final String GET_CLAIMS_SORTED_BY_CLAIM_AMOUNT = "com.danco.training.zaneuskaya.service.impl.ClaimServiceImpl;getClaimsSortedByClaimAmount";

	private static final String GET_LIST = "com.danco.training.zaneuskaya.service.impl.ClaimServiceImpl;getList";

	private static final String GET_CLAIMS_SORTED_BY_ALPHABET = "com.danco.training.zaneuskaya.service.impl.ClaimServiceImpl;getClaimsSortedByAlphabet";

	private static final String READ_CLAIM_LIST_FROM_FILE_MESSAGE = "Enter directory and file name  :";

	private static final String SAVED_BY_DEFAULT_IN = "Saved by default in ";

	private static final String FILE_TO_SAVE_DESTINATION = "d:\\file2.csv";

	private static final String SAVE_CLAIM_LIST_TO_FILE_MESSAGE = "Enter directory and file name for saving";

	private static final String SUBMIT_CLAIM_MESSAGE = "Enter claim's to submit Id";

	private static final String DELETE_CLAIM_MESSAGE = "Enter claim's id to remove ";

	private static final String UPDATE_CLAIM_MESSAGE = "Enter claim's Id for modifying";

	private static final String CLAIM_NOT_EXISTED = "Claim not existed";

	private static final String PRINT_CLAIM_INFO_MESSAGE = "Enter claim Id to show";

	private static final String ENTER_AMOUNT_OF_THE_CLAIM = "Enter amount of the claim";

	private static final String ENTER_BOOK_ID_FOR_CLAIM_CREATION = "Enter book id for claim creation ";

	private static final String PRINT_CLAIM_LIST_SORTED_BY_CLAIM_AMOUNT_MESSAGE = "Claims in ClaimStorage sorted by claim amount";

	private static final String PRINT_CLAIM_LIST_SORTED_BY_ALPHABET_MESSAGE = "Claims in ClaimStorage sorted by alphabet";

	private static final String PRINT_CLAIM_LIST_MESSAGE = "Claims in ClaimStorage";

	BookController bookController = (BookController) DependencyConfiguration
			.getInstanceByClassName(BookController.class);

	@SuppressWarnings("unchecked")
	public void printClaimList() {
		IOUtil.write(PRINT_CLAIM_LIST_MESSAGE);
		List<Claim> claims;
		try {
			claims = (List<Claim>) MessageAnalyzer
					.executeMethod(GET_LIST, null);

			for (Claim claim : claims) {
				IOUtil.write(claimInfo(claim.getId()));

			}

		} catch (ClassNotFoundException | IOException e) {
			IOUtil.write(e.getMessage());
		}

	}

	public void printClaimListSortedByAlphabet() {
		IOUtil.write(PRINT_CLAIM_LIST_SORTED_BY_ALPHABET_MESSAGE);

		List<Claim> sortedClaims = null;
		try {

			sortedClaims = (List<Claim>) MessageAnalyzer.executeMethod(
					GET_CLAIMS_SORTED_BY_ALPHABET, new Object[] {});
			for (Claim claim : sortedClaims) {
				IOUtil.write(claimInfo(claim.getId()));
			}
		} catch (IOException e) {
			IOUtil.write(e.getMessage());
		} catch (ClassNotFoundException e) {
			IOUtil.write(e.getMessage());
		}

	}

	public void printClaimListSortedByClaimAmount() {
		IOUtil.write(PRINT_CLAIM_LIST_SORTED_BY_CLAIM_AMOUNT_MESSAGE);

		List<Claim> sortedClaims = null;
		try {

			sortedClaims = (List<Claim>) MessageAnalyzer.executeMethod(
					GET_CLAIMS_SORTED_BY_CLAIM_AMOUNT, new Object[] {});
			for (Claim claim : sortedClaims) {

				IOUtil.write(claimInfo(claim.getId()));
			}
		} catch (IOException e) {
			IOUtil.write(e.getMessage());
		} catch (ClassNotFoundException e) {
			IOUtil.write(e.getMessage());
		}

	}

	public void createClaim() {

		IOUtil.write(ENTER_BOOK_ID_FOR_CLAIM_CREATION);

		bookController.printBookList();
		Integer bookId = IOUtil.readInt();
		IOUtil.write(ENTER_AMOUNT_OF_THE_CLAIM);
		int claim = IOUtil.readInt();

		try {

			Book book = (Book) MessageAnalyzer.executeMethod(BOOK_SERVICE_GET_BY_ID, new Object[] { bookId });

			Claim newClaim = new Claim(book, claim, false);
			MessageAnalyzer
					.executeMethod(ADD_ENTITY, new Object[] { newClaim });
		} catch (IOException e) {
			IOUtil.write(e.getMessage());
		} catch (ClassNotFoundException e) {
			IOUtil.write(e.getMessage());
		}

	}

	public void printClaimInfo() {

		Claim claim = null;
		int id = IOUtil.readInt();
		IOUtil.write(PRINT_CLAIM_INFO_MESSAGE);
		while (claim == null) {
			IOUtil.write(CLAIM_NOT_EXISTED);
			IOUtil.write(PRINT_CLAIM_INFO_MESSAGE);
			id = IOUtil.readInt();
			try {
				claim = (Claim) MessageAnalyzer.executeMethod(GET_BY_ID,
						new Object[] { id });
				IOUtil.write(claimInfo(claim.getId()));
			} catch (IOException e) {
				IOUtil.write(e.getMessage());
			} catch (ClassNotFoundException e) {
				IOUtil.write(e.getMessage());
			}
		}

	}

	public void updateClaim() {
		Claim claim = null;
		while (claim == null) {

			IOUtil.write(UPDATE_CLAIM_MESSAGE);
			int id = IOUtil.readInt();
			try {
				claim = (Claim) MessageAnalyzer.executeMethod(GET_BY_ID,
						new Object[] { id });
				IOUtil.write(ENTER_AMOUNT_OF_THE_CLAIM);

				claim.setClaimAmount(IOUtil.readInt());

				MessageAnalyzer.executeMethod(UPDATE_ENTITY,
						new Object[] { claim });
				IOUtil.write(claimInfo(claim.getId()));
			} catch (IOException e) {
				IOUtil.write(e.getMessage());
			} catch (ClassNotFoundException e) {
				IOUtil.write(e.getMessage());
			}
		}

	}

	public void deleteClaim() {
		Claim claim = null;
		int id = 0;
		while (claim == null) {
			IOUtil.write(CLAIM_NOT_EXISTED);
			IOUtil.write(DELETE_CLAIM_MESSAGE);
			id = IOUtil.readInt();
			try {
				claim = (Claim) MessageAnalyzer.executeMethod(GET_BY_ID,
						new Object[] { id });
				MessageAnalyzer.executeMethod(REMOVE_ENTITY_BY_ID,
						new Object[] { id });
			} catch (IOException e) {
				IOUtil.write(e.getMessage());
			} catch (ClassNotFoundException e) {
				IOUtil.write(e.getMessage());
			}
		}

	}

	public void submitClaim() {
		Claim claim = null;
		int id = 0;
		while (claim == null) {
			IOUtil.write(CLAIM_NOT_EXISTED);
			IOUtil.write(SUBMIT_CLAIM_MESSAGE);
			id = IOUtil.readInt();
			try {
				claim = (Claim) MessageAnalyzer.executeMethod(GET_BY_ID,
						new Object[] { id });
				MessageAnalyzer.executeMethod(ADD_ENTITY,
						new Object[] { claim });
			} catch (IOException e) {
				IOUtil.write(e.getMessage());
			} catch (ClassNotFoundException e) {
				IOUtil.write(e.getMessage());
			}
		}

	}

	public void saveClaimListToFile() {
		IOUtil.write(SAVE_CLAIM_LIST_TO_FILE_MESSAGE);
		String file = IOUtil.read();
		if (file.isEmpty()) {
			file = FILE_TO_SAVE_DESTINATION;
			IOUtil.write(SAVED_BY_DEFAULT_IN + FILE_TO_SAVE_DESTINATION);

		}
		try {
			MessageAnalyzer.executeMethod(SAVE_ENTITY_LIST_TO_FILE,
					new Object[] { file });
		} catch (IOException e) {
			IOUtil.write(e.getMessage());
		} catch (ClassNotFoundException e) {
			IOUtil.write(e.getMessage());
		}

	}

	public void readClaimListFromFile() {

		IOUtil.write(READ_CLAIM_LIST_FROM_FILE_MESSAGE);
		String file = IOUtil.read();
		if (file.isEmpty()) {
			file = FILE_TO_SAVE_DESTINATION;
			IOUtil.write(SAVED_BY_DEFAULT_IN + FILE_TO_SAVE_DESTINATION);

		}
		List<Claim> claims = null;
		try {
			claims = (List<Claim>) MessageAnalyzer.executeMethod(
					READ_ENTITY_LIST_FROM_FILE, new Object[] { file });
			for (Claim c : claims) {

				MessageAnalyzer.executeMethod(ADD_ENTITY, new Object[] { c });
			}
		} catch (IOException e1) {
			IOUtil.write(e1.getMessage());
		} catch (ClassNotFoundException e) {
			IOUtil.write(e.getMessage());
		}

	}

	public String claimInfo(int id) {

		StringBuffer str = new StringBuffer();
		Claim c = null;
		try {
			c = (Claim) MessageAnalyzer.executeMethod(GET_BY_ID,
					new Object[] { id });
			str.append(" ");
			str.append(c.getId());
			str.append(" ");
			str.append(c.getBook().getId());
			str.append(" ");
			str.append(c.getClaimAmount());
			str.append(" ");
			str.append(c.isExecuted());
			str.append(" ");
			str.append(c.getBook().getTitle());
		} catch (ClassNotFoundException | IOException e) {
			IOUtil.write(e.getMessage());
		}

		return str.toString();
	}

}
